﻿using HDSmartCommunity.DAL;
using HDSmartCommunity.Models;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using static HDSmartCommunity.Startup;

namespace HDSmartCommunity.BUS.MqttBUS
{
    public class FXMqttClient
    {
        IMqttClient _mqttClient;
        MqttClientOptions _options;
        public string SubscribeTopic = "";
        public string topic_2 = "";
        MqttInfo mqttInfo;

        public FXMqttClient()
        {
            MqttDAL mqttDAL = new MqttDAL();
            mqttInfo = mqttDAL.GetMqttInfo();
            string mode = AppSettingsHelper.Configuration["DataSimulation"];
            if (mode == "0")
            {
                SubscribeTopic = AppSettingsHelper.Configuration["Topic"];
                //SubscribeTopic = string.Format("{0}/{1}/{2}/{3}/{4}/{5}", mqttInfo.version, mqttInfo.line, mqttInfo.station, mqttInfo.message_type, mqttInfo.iot_node_id, mqttInfo.device_id);
            }
            else if (mode == "1")
            {
                SubscribeTopic = AppSettingsHelper.Configuration["Topic"];
                //SubscribeTopic = string.Format("{0}/{1}/{2}/{3}/{4}/11111", mqttInfo.version, mqttInfo.line, mqttInfo.station, mqttInfo.message_type, mqttInfo.iot_node_id, mqttInfo.device_id);
                topic_2 = AppSettingsHelper.Configuration["Topic_2"];
            }
            else if (mode == "2")
            {
                SubscribeTopic = AppSettingsHelper.Configuration["Topic"];
                //SubscribeTopic = string.Format("{0}/{1}/{2}/sys/property/up", mqttInfo.version, mqttInfo.number, mqttInfo.device_id);
                topic_2 = string.Format("{0}/{1}/{2}/sys/property/up", mqttInfo.version, AppSettingsHelper.Configuration["ProductKey"], AppSettingsHelper.Configuration["SerialNumber"]);
            }
            else if (mode == "3")
            {
                SubscribeTopic = AppSettingsHelper.Configuration["Topic"];
            }

            Init();
        }

        public IMqttClient MqttClient { get { return _mqttClient; } }

        public MqttClientOptions Options { get { return _options; } }

        private void Init()
        {
            _mqttClient = new MqttFactory().CreateMqttClient();

            _mqttClient.UseApplicationMessageReceivedHandler(c =>
            {
                /*string state = System.Text.Encoding.ASCII.GetString(c.ApplicationMessage.Payload);
                string device_id = c.ApplicationMessage.Topic*//*.Replace("$SYS/broker/chen_state/", "")*//*;
                //MqttClientBUS.UpdateOnOffLine(loginName, state);
                IMqttDevices devices = (IMqttDevices)ServicesLocator.Instance.GetService(typeof(IMqttDevices));
                if (state.Equals("0"))
                    devices.StopFromUserNameAsync(device_id);*/
            });
            _mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(e =>
            {
                StartConnect();
            });
            _options = new MqttClientOptions()
            {
                /*ClientId = CommVars.Configuration.GetSection("MqttServer").GetSection("ClientId").Value,*/
                ClientId = Guid.NewGuid().ToString().Substring(0, 13) + "&" + mqttInfo.version
            };
            _options.ChannelOptions = new MqttClientTcpOptions()
            {
                //Server = AppSettingsHelper.Configuration["MqttServer:Server"],
                Server = mqttInfo.mqtt_server,
                //Port = int.Parse(AppSettingsHelper.Configuration["MqttServer:Port"])
                Port = mqttInfo.mqtt_port,
            };
            //string strName = AppSettingsHelper.Configuration["MqttServer:Username"];
            string strName = mqttInfo.mqtt_uname;
            if (!string.IsNullOrEmpty(strName))
            {
                _options.Credentials = new MqttClientCredentials()
                {
                    Username = strName,
                    Password = System.Text.Encoding.Default.GetBytes(mqttInfo.mqtt_pwd)
                };
            }
            _options.CleanSession = true;
            _options.KeepAlivePeriod = TimeSpan.FromSeconds(60);
            StartConnect();
        }

        public void StartConnect()
        {
            Task t = Task.Factory.StartNew(async () =>
            {
                while (true)
                {
                    if (!_mqttClient.IsConnected)
                    {
                        await _mqttClient.ConnectAsync(_options);
                        await _mqttClient.SubscribeAsync(SubscribeTopic, MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);
                        if (!string.IsNullOrEmpty(topic_2))
                        {
                            await _mqttClient.SubscribeAsync(topic_2, MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);
                        }
                    }
                    else break;
                    Task.Delay(3000).Wait();
                }
            });
        }
    }
}
